home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * LogUtil.c
- *
- * Logging functions
- *
- * This is a support file for "Grant's CGI Framework".
- * Please see the license agreement that accompanies the distribution package
- * for licensing details.
- *
- * Copyright ©1995,1996 by Grant Neufeld
- * grant@acm.com
- * http://arpp.carleton.ca/grant/mac/grantscgi/
- *
- *****/
-
- #include "MyConfiguration.h"
- #if kCompileWithLogSupport
-
- #if !kCompileWithProcessFileSpec
- #error "Logging requires the kCompileWithProcessFileSpec to be set on in MyConfiguration.h"
- #endif
-
- #include <string.h>
-
- #include "compiler_stuff.h"
-
- #include "constants.h"
- #include "globals.h"
-
- #include "DebugUtil.h"
- #include "FileUtil.h"
-
- #include "LogUtil.h"
-
-
- /*** LOCAL VARIABLES ***/
-
- static OSErr vLogInitialized = false; /* logging has been initialized */
- static OSErr vLogFileError = true; /* returned if LogStartup fails - logging can't be done */
- static FSSpec vLogFileSpec; /* the location of the log file */
- static short vLogFileRef = nil; /* the reference of the open log file - nil if closed */
- static Boolean vLogNeedsFlush = false; /* there is data that has been written but not flushed */
-
-
- /*** LOCAL CONSTANTS ***/
-
- #define krLogFileCreatorType 3002
- /* default to SimpleText/TeachText if creator type resource not available */
- #define kLogFileDefaultCreatorType 'ttxt'
-
-
- /*** LOCAL MACROS ***/
-
- #define logFileEnsureOpen() ((vLogFileRef == nil)? LogFileOpen() : noErr)
-
-
- /*** LOCAL PROTOTYPES ***/
-
- /*** FUNCTIONS ***/
-
- /* Initialize the log file. */
- OSErr
- LogStartup ( void )
- {
- Str255 logFileName;
- Handle logFileCreatorHdl; /* the resource containing the creator type */
- OSType creatorType; /* used when creating new log file */
- Boolean isFolder; /* used for Finder alias resolving */
- Boolean wasAliased; /* used for Finder alias resolving */
-
- vLogInitialized = true;
- vLogFileError = noErr;
- vLogFileRef = nil;
- logFileName[nil] = nil;
- vLogNeedsFlush = false;
-
- /* get the name of the log file */
- GetIndString ( logFileName, krFilenamesStrs, kriFilenameLog );
- if ( logFileName[nil] == nil )
- {
- /* string of file name is invalid */
- vLogFileError = ResError ();
- }
-
- /* build the FSSpec */
- if ( vLogFileError == noErr )
- {
- vLogFileError = FSMakeFSSpec ( gProcessFSSpec.vRefNum, gProcessFSSpec.parID,
- logFileName, &vLogFileSpec );
- }
-
- if ( vLogFileError == fnfErr )
- {
- /* determine the creator type of the log file */
- logFileCreatorHdl = GetResource ( 'TNAM', krLogFileCreatorType );
- if ( logFileCreatorHdl != NULL )
- {
- creatorType = **((OSType **)logFileCreatorHdl);
- ReleaseResource ( logFileCreatorHdl );
- }
- else
- {
- /* use default if creator type resource not found */
- creatorType = kLogFileDefaultCreatorType;
- }
- vLogFileError = FSpCreate ( &vLogFileSpec, creatorType, kTypeText, smSystemScript );
- }
- else if ( vLogFileError == noErr )
- {
- /* resolve if the file is an alias */
- vLogFileError = ResolveAliasFileMountOption ( &vLogFileSpec, true, &isFolder, &wasAliased, false );
- }
-
- if ( vLogFileError == noErr )
- {
- vLogFileError = LogFileOpen ();
- }
-
- #if kCompileWithDebugLogging
- if ( vLogFileError == noErr )
- {
- LogStringAndSeparatorP ( gProcessFSSpec.name, ' ' );
- LogStringBreakP ( gVersionStr );
- }
- #endif
-
- return vLogFileError;
- } /* LogStartup */
-
-
- /* */
- OSErr
- LogQuit ( void )
- {
- OSErr theErr;
-
- if ( (vLogFileError == noErr) && (vLogFileRef != nil) )
- {
- theErr = LogFileClose ();
- }
- else
- {
- theErr = noErr;
- }
-
- return theErr;
- } /* LogQuit */
-
-
- #pragma mark -
-
- /* Open the log file for writing. Writing will begin at the end of the file (appending) */
- OSErr
- LogFileOpen ( void )
- {
- OSErr theErr;
-
- if ( vLogFileError == noErr )
- {
- my_assert ( vLogFileRef == nil, "\pLogFileOpen: vLogFileRef is not nil - file already open" );
-
- /* open the data fork for writing */
- theErr = FSpOpenDF ( &vLogFileSpec, fsWrPerm, &vLogFileRef );
- if ( theErr == noErr )
- {
- /* set the file position to the end of the file */
- theErr = SetFPos ( vLogFileRef, fsFromLEOF, nil );
- }
- else
- {
- /* there was an error */
- vLogFileRef = nil;
- }
- }
- else
- {
- theErr = vLogFileError;
- }
-
- return theErr;
- } /* LogFileOpen */
-
-
- /* Close the log file. */
- OSErr
- LogFileClose ( void )
- {
- OSErr theErr;
-
- if ( vLogFileError == noErr )
- {
- my_assert ( vLogFileRef != nil, "\pLogFileClose: vLogFileRef is nil" );
-
- theErr = FSClose ( vLogFileRef );
- vLogFileRef = nil;
- }
- else
- {
- theErr = vLogFileError;
- }
-
- return theErr;
- } /* LogFileClose */
-
-
- /* ••• need to upgrade this to just flush the data to disk - but I'm in a rush to
- get this at least working...
- This function should be called periodically after data has been written to the
- log file. It helps to ensure that the data is not lost if there is a crash before
- the file is closed. */
- p_export
- OSErr
- LogFileFlush ( void )
- {
- OSErr theErr;
-
- if ( vLogNeedsFlush )
- {
- theErr = LogFileClose ();
- theErr = LogFileOpen ();
- vLogNeedsFlush = false;
- }
- else
- {
- theErr = noErr;
- }
-
- return theErr;
- } /* LogFileFlush */
-
-
- #pragma mark -
-
- /* Takes a C format string and writes it to the log file.
- Does not append linebreak or any other character so the next write to the log file
- will follow directly after this write. If you want to have theString followed by
- a linebreak, you need to call one of the functions that appends a separator
- character after theString. */
- p_export
- OSErr
- LogString ( const char *theString )
- {
- OSErr theErr;
- long stringLength;
-
- my_assert ( theString != NULL, "\pLogString: theString is NULL" );
-
- if ( !vLogInitialized )
- {
- return noErr;
- }
-
- if ( (vLogFileError == noErr) && (theString[nil] != nil) )
- {
- theErr = logFileEnsureOpen ();
- if ( theErr == noErr )
- {
- stringLength = strlen ( theString );
-
- /* write the line + end null byte to the file */
- theErr = FSWrite ( vLogFileRef, &stringLength, theString );
- if ( theErr == noErr )
- {
- vLogNeedsFlush = true;
- }
- }
- }
- else
- {
- theErr = vLogFileError;
- }
-
- return theErr;
- } /* LogString */
-
-
- /* Same as 'LogString', except theString is a Pascal format string (max 255 characters) */
- p_export
- OSErr
- LogStringP ( const StringPtr theString )
- {
- OSErr theErr;
- long stringLength;
-
- my_assert ( theString != NULL, "\pLogStringP: theString is NULL" );
-
- if ( !vLogInitialized )
- {
- return noErr;
- }
-
- if ( (vLogFileError == noErr) && (theString[nil] != nil) )
- {
- theErr = logFileEnsureOpen ();
- if ( theErr == noErr )
- {
- stringLength = (unsigned char) (theString[nil]);
-
- /* write the line + end null byte to the file */
- theErr = FSWrite ( vLogFileRef, &stringLength, theString + 1 );
- if ( theErr == noErr )
- {
- vLogNeedsFlush = true;
- }
- }
- }
- else
- {
- theErr = noErr;
- }
-
- return theErr;
- } /* LogStringP */
-
-
- /* Takes a C format string and writes it to the log file.
- Appends theSeparator after theString. This may be used for writing theString
- followed by a linefeed, or perhaps a tab character, among other uses. */
- p_export
- OSErr
- LogStringAndSeparator ( const char *theString, char theSeparator )
- {
- OSErr theErr;
- long stringLength;
-
- my_assert ( theString != NULL, "\pLogStringAndSeparator: theString is NULL" );
-
- if ( !vLogInitialized )
- {
- return noErr;
- }
-
- if ( vLogFileError == noErr )
- {
- theErr = logFileEnsureOpen ();
- if ( theErr == noErr )
- {
- if ( theString[nil] != nil )
- {
- stringLength = strlen ( theString );
-
- /* write the line + end null byte to the file */
- theErr = FSWrite ( vLogFileRef, &stringLength, theString );
- }
-
- /* write the newline char to the file */
- stringLength = 1;
- theErr = FSWrite ( vLogFileRef, &stringLength, &theSeparator );
- if ( theErr == noErr )
- {
- vLogNeedsFlush = true;
- }
- }
- }
- else
- {
- theErr = noErr;
- }
-
- return theErr;
- } /* LogStringAndSeparator */
-
-
- /* Same as 'LogStringAndSeparator', except theString is a Pascal format string
- (max 255 characters) */
- p_export
- OSErr
- LogStringAndSeparatorP ( const StringPtr theString, char theSeparator )
- {
- OSErr theErr;
- long stringLength;
-
- my_assert ( theString != NULL, "\pLogStringAndSeparatorP: theString is NULL" );
-
- if ( !vLogInitialized )
- {
- return noErr;
- }
-
- if ( vLogFileError == noErr )
- {
- theErr = logFileEnsureOpen ();
- if ( theErr == noErr )
- {
- if ( theString[nil] != nil )
- {
- stringLength = (unsigned char) (theString[nil]);
-
- /* write the line + end null byte to the file */
- theErr = FSWrite ( vLogFileRef, &stringLength, theString + 1 );
- }
-
- /* write the newline char to the file */
- stringLength = 1;
- theErr = FSWrite ( vLogFileRef, &stringLength, &theSeparator );
- if ( theErr == noErr )
- {
- vLogNeedsFlush = true;
- }
- }
- }
- else
- {
- theErr = noErr;
- }
-
- return theErr;
- } /* LogStringAndSeparatorP */
-
-
- /** DEBUG LOGGING **/
- #pragma mark -
- #if kCompileWithDebugLogging
-
- /* These functions will prepend "DEBUG: " in the log file before writing theString
- that is passed to them.
- The functions are prototyped in "LogUtil.h" to map to NULL (do nothing) if
- the 'kCompileWithDebugLogging' option is off in "MyConfiguration.h" */
-
- /* */
- p_export
- OSErr
- LogStringDebug ( const char *theString )
- {
- OSErr theErr;
-
- theErr = LogStringP ( "\pDEBUG: " );
- theErr = LogStringAndSeparator ( theString, kLogLinebreak );
-
- return theErr;
- } /* LogStringDebug */
-
-
- /* */
- p_export
- OSErr
- LogStringDebugP ( const StringPtr theString )
- {
- OSErr theErr;
-
- theErr = LogStringP ( "\pDEBUG: " );
- theErr = LogStringAndSeparatorP ( theString, kLogLinebreak );
-
- return theErr;
- } /* LogStringDebugP */
-
- #endif /* kCompileWithDebugLogging */
-
-
- #endif /* kCompileWithLogSupport */
- /***** EOF *****/
-